import com.intellij.notification.*;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @description: 删除该类中没有被使用的属性
 * @author: chengsheng@qbb6.com
 * @date: 2018/12/1
 */
public class RmUnusedField extends AnAction {

    private static NotificationGroup notificationGroup;

    static{
        notificationGroup = new NotificationGroup("Java2Json.NotificationGroup", NotificationDisplayType.BALLOON, true);
    }

    @Override
    public void actionPerformed(AnActionEvent e) {
        Editor editor = (Editor) e.getDataContext().getData(CommonDataKeys.EDITOR);
        PsiFile psiFile = (PsiFile) e.getDataContext().getData(CommonDataKeys.PSI_FILE);
        Project project = editor.getProject();
        PsiElement referenceAt = psiFile.findElementAt(editor.getCaretModel().getOffset());
        PsiClass selectedClass = (PsiClass) PsiTreeUtil.getContextOfType(referenceAt, new Class[]{PsiClass.class});
        try{
            List<String> fieldNames=removeField(selectedClass,project);
            Notification info=null;
            if (fieldNames.size() > 0) {
                info = notificationGroup.createNotification("Success remove:" + fieldNames, NotificationType.INFORMATION);
            } else {
                info = notificationGroup.createNotification("No field unused!", NotificationType.INFORMATION);
            }
            Notifications.Bus.notify(info, project);
        }catch (Exception ex){
            Notification error = notificationGroup.createNotification("remove unused field error", NotificationType.ERROR);
            Notifications.Bus.notify(error, project);
        }

    }

    public List<String> removeField(PsiClass psiClass,Project project){
        if(Objects.nonNull(psiClass)){
            List<PsiField> psiFields = new ArrayList<>(Arrays.asList(psiClass.getAllFields()));
            if(psiFields!=null && psiFields.size()>0){
                Iterator<PsiField> iterable = psiFields.iterator();
                CopyOnWriteArrayList<String> fieldsName=new CopyOnWriteArrayList<>();
                while (iterable.hasNext()){
                    PsiField psiField=(PsiField)iterable.next();
                    Long count=ReferencesSearch.search(psiField).findAll().stream().count();
                    if(count==0){
                        iterable.remove();
                        WriteCommandAction.runWriteCommandAction(project,() ->{
                            psiField.delete();
                            fieldsName.add(psiField.getName());
                        });
                    }
                }
                return fieldsName;
            }
        }
        return new ArrayList<>();
    }
}
